package org.gwtEss.table;

import java.util.List;

import org.gwtEss.other.DragTrack;
import org.gwtEss.other.HorizontalPanel;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;

public abstract class HeaderTableColWidget extends Composite{
	private final static int SEPERATOR_WIDTH = 2, SORT_WIDTH = 8;
	private static int FILTER_MENU_WIDTH = 16;
	final static int MIN_WIDTH = SEPERATOR_WIDTH + SORT_WIDTH + FILTER_MENU_WIDTH;
	HorizontalPanel hPanel = new HorizontalPanel();
	HTML text = new HTML();
	Image sortImage = new Image();
	Label seperator  = new Label(){
		{
			setSize("2px", "100%");
			addStyleName("seperator-nodrag");
		}
	};/*new Image("images/header-col-split.png")*/;
	FilterMenu filterMenu = new FilterMenu(){

		@Override
		public void onFilterMenuSelect(
				FetchCompleteCallBack<FilterMenuItem> filterListCallBack) {
			HeaderTableColWidget.this.onFilterMenuSelect(filterListCallBack);
		}

		@Override
		public void onFilterMenuClose(List<FilterMenuItem> filterCriterias) {
			HeaderTableColWidget.this.onFilterMenuClose(filterCriterias);
		}};
//	private int width = -1;

	private Boolean sortAsc;
//	private boolean filterMenuVisible = true;
//	private boolean seperatorVisible; 
	private int startX = -1; 
	private DragTrack dt = null;
	private HeaderTableColWidget dependentHeaderTableColWidget;
	
//	public HeaderTableColWidget(int width) {
//		init(false, true);
//		initWidget(hPanel);
//		setWidth(width);
//		setSeperatorVisible(true);
//	}
	
	/*public void setFilterList(List<FilterMenuItem> filterList) {
		setFilterMenuVisible(true);
		filterMenu.setFilterList(filterList);
	}*/
	public HeaderTableColWidget() {
		init(false, true);
		initWidget(hPanel);
		setSeperatorVisible(true);
	}
//	private void setWidth(/*int width*/) {
///*//		this.width = width; 
//		setWidth();
////		setSeperatorVisible(true);
//*/	
//		setWidth(getOffsetWidth());
//	}
//	public int getWidth() {
//		return /*width*/ getOffsetWidth();
//	}
	public HeaderTableColWidget(int width, String htmlText, boolean disableResize) {
		init(disableResize, true);
		initWidget(hPanel);
//		setWidth(width);
		DeferredCommand.addCommand(new Command() {
			
			@Override
			public void execute() {
				resize();
			}
		});
		
		setHTML(htmlText);
		setSeperatorVisible(true);
	}
	public HeaderTableColWidget(String htmlText, boolean disableResize) {
		init(disableResize, true);
		initWidget(hPanel);
		setHTML(htmlText);
		setSeperatorVisible(true);
	}
	@Override
	public void setWidth(String width) {
		super.setWidth(width);
DeferredCommand.addCommand(new Command() {
			
			@Override
			public void execute() {
				resize();
			}
		});
		
	}
	@Override
	public void setPixelSize(int width, int height) {
		super.setPixelSize(width, height);
DeferredCommand.addCommand(new Command() {
			
			@Override
			public void execute() {
				resize();
			}
		});
		
	}
	@Override
	public void setSize(String width, String height) {
		super.setSize(width, height);
DeferredCommand.addCommand(new Command() {
			
			@Override
			public void execute() {
				resize();
			}
		});
		
	}
	private void resize(){
		int width = getOffsetWidth();
		if (width <= 0 )return;
		if (width == -1) return;
		int txtWidth = width;
		if (sortAsc == null){
			sortImage.setVisible(false);
		}else {
			String url= sortAsc?"images/sort_arrow_up.gif":"images/sort_arrow_down.gif";
			sortImage.setUrl(url);
			sortImage.setVisible(true);
			txtWidth -= SORT_WIDTH;
		}
		
//		if (filterMenu.isVisible()){
//		setVisible(filterMenuVisible);
		if (filterMenu.isVisible()){
//			filterMenu.setVisible(true);
			txtWidth -= FILTER_MENU_WIDTH;
		}/*else{
			filterMenu.setVisible(false);
		}*/
		
		if (seperator.isVisible()){
//			seperator.setVisible(true);
			txtWidth -= SEPERATOR_WIDTH;
		}else 
			seperator.setVisible(false);
		
		text.setWidth(txtWidth + "px");
			
		
	}
	public void setSortOrder(Boolean asc){
		this.sortAsc = asc; 
//		setWidth();
		resize();
	}
	private boolean filterMenuVisible = true, seperatorVisible = true; 
	public void setFilterMenuVisible(boolean visible){
		filterMenuVisible = visible;
//		setWidth();
		resize();
		/*if (visible != filterMenu.isVisible()){
			filterMenu.setVisible(visible);
			setWidth();
		}*/
	}
	public void setSeperatorVisible(boolean visible){
//		seperatorVisible = visible;
		seperator.setVisible(visible);
//		setWidth();
		resize();
	}
	private void init(boolean disableResize, boolean filterMenuVisible) {
		this.filterMenuVisible = filterMenuVisible;
		hPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		
		hPanel.addMouseMoveHandler(new MouseMoveHandler(){

			public void onMouseMove(MouseMoveEvent event) {
				if(HeaderTableColWidget.this.filterMenuVisible){
					filterMenu.setVisible(true);
//					setWidth();
					resize();
				}
				
			}
			
		});
		hPanel.addMouseOutHandler(new MouseOutHandler(){

			public void onMouseOut(MouseOutEvent event) {
				if(HeaderTableColWidget.this.filterMenuVisible){
					filterMenu.setVisible(false);
//					setWidth();
					resize();
				}
			}
			
		});
		hPanel.add(text);
		hPanel.add(sortImage);
		hPanel.add(filterMenu);
		hPanel.add(seperator);
		hPanel.setHeight("25px");
		if (!disableResize)
			seperator.addStyleName("seperator-drag");
		text.addStyleName("divClip");
		sortImage.setVisible(false);
		filterMenu.setVisible(false);
		seperator.setVisible(false);
		initListeners(disableResize);
//		setWidth();
	}
	private void doSort(){
		if (sortAsc != null)
			sortAsc = !sortAsc;
		else 
			sortAsc = true;
//		setWidth();
		resize();
		onColSort(sortAsc);
		System.out.println("time to sort");		
	}
	private void initListeners(boolean disableResize) {

		text.addClickHandler(new ClickHandler(){

			public void onClick(ClickEvent event) {
				doSort();
			}
			
		});
		if (!disableResize)
		seperator.addMouseDownHandler(new MouseDownHandler(){

			public void onMouseDown(MouseDownEvent event) {
				event.preventDefault();
				startX = event.getClientX();
				dt = new DragTrack(){
					boolean firstResizeDone = false; 
					@Override
					public void onMouseMove(int mouseX) {

//						int delta =  mouseX - startX;
//						mouseX = startX;
						doAdjustWidths(mouseX);
					}
					/*
					private void doAdjustWidths(int delta) {
						System.out.println("delta: " + delta);
						width += delta;
						setWidth();
					}
*/
					
				/*	private void doAdjustWidths(int mouseX){
						int delta =  mouseX - startX;
//						int rightColNum = visibleCols.indexOf(col) + 1;
//						ColWidget rightCol = visibleCols.get(rightColNum);
						if (!firstResizeDone && delta != 0){
							firstResizeDone = true;
							onResizeBegin();
						}
						if (delta == 0){
							return;
						}
//						Grid rightGrid = (Grid) flexTable.getWidget(0, rightColNum);
						int colWidth = width + delta;
//						int rightColWidth =rightCol.getColWidth() - delta; 
						
						if (colWidth <= MIN_WIDTH)
							return;
						
//						grid.setWidth(colWidth + "px");
						width = colWidth;
						setWidth();
//						rightGrid.setWidth(rightColWidth + "px");

//						rightCol.setColWidth(rightColWidth);
//						col.setColWidth(col.getColWidth() + delta);

//						changeText(grid, colWidth, col);
//						changeText(rightGrid, rightColWidth, rightCol);
						startX = mouseX;
					
					}*/
					private void doAdjustWidths(int mouseX){
						int delta =  mouseX - startX;
//						int rightColNum = visibleCols.indexOf(col) + 1;
//						ColWidget rightCol = visibleCols.get(rightColNum);
						if (!firstResizeDone && delta != 0){
							firstResizeDone = true;
							onResizeBegin();
						}
						if (delta == 0){
							return;
						}
//						Grid rightGrid = (Grid) flexTable.getWidget(0, rightColNum);
						int colWidth = getOffsetWidth() + delta;
						int rightColWidth =/*rightCol.getColWidth()*/dependentHeaderTableColWidget.getOffsetWidth()/*getWidth()*/ - delta; 
						
						if (colWidth <= MIN_WIDTH || rightColWidth <=MIN_WIDTH)
							return;
						
//						grid.setWidth(colWidth + "px");
						/*width = colWidth;*/
//						setWidth();
						resize();
//						rightGrid.setWidth(rightColWidth + "px");

						dependentHeaderTableColWidget.setWidth(rightColWidth + "px");
//						col.setColWidth(col.getColWidth() + delta);

//						changeText(grid, colWidth, col);
//						changeText(rightGrid, rightColWidth, rightCol);
						startX = mouseX;
					
					}
					private void onResizeBegin() {
						System.out.println("resize begin");
						onColResizeBegin();
					}
					@Override
					public void onMouseUp(int mouseX) {
						doAdjustWidths(mouseX);
						dt = null;
						
						if (firstResizeDone){
//							int rightColNum = visibleCols.indexOf(col) + 1;
//							ColWidget rightCol = visibleCols.get(rightColNum);
							onColResizeEnd();
						}
					}
					private void onResizeEnd() {
						onResizeEnd();
						System.out.println("resize end");
					}};
			}
			
		});
	}
	public void setHTML(String txt) {
		text.setHTML(txt);
	}
	public void associateDependentColWidget(
			HeaderTableColWidget dependentHeaderTableColWidget) {
		this.dependentHeaderTableColWidget = dependentHeaderTableColWidget;
	}
	public abstract void onColResizeBegin();
	public abstract void onColResizeEnd();
	public abstract void onColSort(Boolean sortAsc);
	public abstract void onFilterMenuSelect(
			FetchCompleteCallBack<FilterMenuItem> filterListCallBack);
	public abstract void onFilterMenuClose(List<FilterMenuItem> filterCriterias);
	
}
